﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WellDone
{
    class Globals
    {
        // Numeric Constants
        public const double k_dbl_margin_size = 15.0;
        public const int k_int_status_open = 0;
        public const int k_int_status_sent = 1;
        public const int k_int_status_ready = 2;
        public const int k_int_status_delivered = 3;
        public const int k_int_status_closing = 4;
        public const int k_int_status_closed = 5;
        public const int k_int_num_horizontal_orders = 5;
        // Misc. Data
        public static int token;
        public static ServiceReferenceOpenRPOS.ServiceOpenRPOSClient client = new ServiceReferenceOpenRPOS.ServiceOpenRPOSClient();
        public static ObservableCollection<ServiceReferenceOpenRPOS.MenuItem> MenuItemRecords = new ObservableCollection<ServiceReferenceOpenRPOS.MenuItem>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail> OrderDetailRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderOption> OrderOptionRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderOption>();
        public static ObservableCollection<ServiceReferenceOpenRPOS.OrderSummary> OrderSummaryRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderSummary>();
        private static DateTime dtLastSent = new DateTime(2013, 1, 1);

        // Returns "True" if new records are loaded, "False" otherwise...
        public static async Task<Boolean> loadSentOrders()
        {
            ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail> NewOrderDetailRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail>();
            ObservableCollection<ServiceReferenceOpenRPOS.OrderOption> NewOrderOptionRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderOption>();
            ObservableCollection<ServiceReferenceOpenRPOS.OrderSummary> NewOrderSummaryRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderSummary>();
            // Return any new sent orders
            string filter = "status=" + Globals.k_int_status_sent.ToString() + " and TimeSent>'" + dtLastSent.ToString() + "' order by ID";
            NewOrderSummaryRecords = await Globals.client.GetOrderSummaryObjectsAsync(Globals.token, filter);
            System.Diagnostics.Debug.WriteLine("Checking for orders... " + NewOrderSummaryRecords.Count.ToString());
            bool bReturn = false;
            if (NewOrderSummaryRecords.Count > 0)
            {
                bReturn = true;
                // Get the IDs of the updated order summary records...
                string strOrderSummaryIDs = "(";
                foreach (ServiceReferenceOpenRPOS.OrderSummary os in NewOrderSummaryRecords)
                {
                    strOrderSummaryIDs += os.col_ID.ToString() + ",";
                }
                strOrderSummaryIDs = strOrderSummaryIDs.Substring(0, strOrderSummaryIDs.Length - 1) + ")";
                // Get the detail records...
                filter = "OrderSummaryID in " + strOrderSummaryIDs + " order by ID";
                NewOrderDetailRecords = await Globals.client.GetOrderDetailObjectsAsync(Globals.token, filter);
                // Get the IDs of the updated order summary records...
                string strOrderDetailIDs = "(";
                foreach (ServiceReferenceOpenRPOS.OrderDetail od in NewOrderDetailRecords)
                {
                    strOrderDetailIDs += od.col_ID.ToString() + ",";
                }
                strOrderDetailIDs = strOrderDetailIDs.Substring(0, strOrderDetailIDs.Length - 1) + ")";
                // Get the option records...
                filter = "OrderDetailID in " + strOrderDetailIDs + " order by ID";
                NewOrderOptionRecords = await Globals.client.GetOrderOptionObjectsAsync(Globals.token, filter);
                // Add/Update new order summary records
                foreach (ServiceReferenceOpenRPOS.OrderSummary os in NewOrderSummaryRecords)
                {
                    // Set the "Last Sent" value
                    if (Globals.dtLastSent < os.col_TimeSent)
                        Globals.dtLastSent = os.col_TimeSent;
                    if (Globals.OrderSummaryRecords.Where(x => x.col_ID == os.col_ID).Count()==0)
                    {
                        // Add to the list of order summary records
                        Globals.OrderSummaryRecords.Add(os);
                        // Add corresponding detail and option records
                        foreach (ServiceReferenceOpenRPOS.OrderDetail od in NewOrderDetailRecords.Where(x => x.col_OrderSummaryID == os.col_ID))
                        {
                            // Add to the list of order detail records
                            Globals.OrderDetailRecords.Add(od);
                            // Get corresponding option records
                            foreach (ServiceReferenceOpenRPOS.OrderOption oo in NewOrderOptionRecords.Where(x => x.col_OrderDetailID == od.col_ID))
                            {
                                // Add to the list of order option records
                                Globals.OrderOptionRecords.Add(oo);
                            }
                        }
                    }
                    else
                    {
                        // Update the order summary records
                        ServiceReferenceOpenRPOS.OrderSummary oldSummaryRecord = Globals.OrderSummaryRecords.Where(x => x.col_ID == os.col_ID).First();
                        Globals.OrderSummaryRecords.Remove(oldSummaryRecord);
                        Globals.OrderSummaryRecords.Add(os);
                        // Update corresponding order detail records
                        ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail> OldOrderDetailRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderDetail>();
                        foreach (ServiceReferenceOpenRPOS.OrderDetail oldDetailRecord in Globals.OrderDetailRecords.Where(x => x.col_OrderSummaryID == os.col_ID))
                            OldOrderDetailRecords.Add(oldDetailRecord);
                        foreach (ServiceReferenceOpenRPOS.OrderDetail oldDetailRecord in OldOrderDetailRecords)
                            Globals.OrderDetailRecords.Remove(oldDetailRecord);
                        foreach (ServiceReferenceOpenRPOS.OrderDetail od in NewOrderDetailRecords.Where(x => x.col_OrderSummaryID == os.col_ID))
                        {
                            // Update order detail records
                            Globals.OrderDetailRecords.Add(od);
                            // Update corresponding order option records
                            ObservableCollection<ServiceReferenceOpenRPOS.OrderOption> OldOptionRecords = new ObservableCollection<ServiceReferenceOpenRPOS.OrderOption>();
                            foreach (ServiceReferenceOpenRPOS.OrderOption oldOptionRecord in Globals.OrderOptionRecords.Where(x => x.col_OrderDetailID == od.col_ID))
                                OldOptionRecords.Add(oldOptionRecord);
                            foreach (ServiceReferenceOpenRPOS.OrderOption oldOptionRecord in OldOptionRecords)
                                Globals.OrderOptionRecords.Remove(oldOptionRecord);
                            foreach (ServiceReferenceOpenRPOS.OrderOption oo in NewOrderOptionRecords.Where(x => x.col_OrderDetailID == od.col_ID))
                            {
                                // Add to the list of order option records
                                Globals.OrderOptionRecords.Add(oo);
                            }
                        }
                    }
                }
            }
            // Return the result...
            return bReturn;
        }

    }
}
